﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace POC_EntityFramework
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Program started!");

            // example of entity with linq, different ways are used through out examples to different ways
            // NO EXCEPTION HANDLING!!!!

            //PrintCinemasWithMovies();

            //PrintMoviesForActor("Rasmus");

            //AddMovie();

            //UpdateMovie();

            //DeleteMovie();

            Console.WriteLine("Program done!");

            Console.ReadLine();
        }

        private static void PrintCinemasWithMovies()
        {
            using (dmaa0212a_5Entities context = new dmaa0212a_5Entities())
            {
                //var cinemas = context.Cinemas;
                // same as = from c in context.Cinemas select c;
                // done directly in foreach loop

                foreach (var cinema in context.Cinemas)
                {
                    Console.WriteLine("{0} in {1} shows following movies:",cinema.name,cinema.location);
                    foreach (var movie in cinema.Movies)
                    {
                        Console.WriteLine("\tTitle: {0}\n\tLength: {1}\n\tPrice: {2}", movie.Title, movie.Length, movie.Price);
                        Console.WriteLine("----------------------------------------");
                    }
                    Console.WriteLine();
                }
            }
        }

        private static void PrintMoviesForActor(string actorName)
        {
            using (dmaa0212a_5Entities context = new dmaa0212a_5Entities())
            {
                // find actor
                var actor =
                    (from a in context.Actors
                    where a.name == actorName
                    select a).Single();

                Console.WriteLine("Movies where the actor {0} is playing",actorName);
                foreach (var item in actor.Movies)
                {
                    Console.WriteLine(item.Title);
                }
            }
        }

        private static void AddMovie()
        {
            using (dmaa0212a_5Entities context = new dmaa0212a_5Entities())
            {
                Console.WriteLine("Adding Die Hard 2");

                // create new movie
                Movie movie = new Movie();
                movie.Title = "Die Hard 2";
                movie.Length = 120;
                movie.Price = 85;
                movie.Genre = "Action";
                movie.Description = "Booom 2";
                
                // add actors (all actors with s in their name
                var actors =
                    from a in context.Actors
                    where a.name.Contains("s")
                    select a;
                foreach (var item in actors)
                {
                    movie.Actors.Add(item);
                }

                // add cinemas
                var cinemas =
                    from c in context.Cinemas
                    where c.location == "København"
                    select c;
                foreach (var item in cinemas)
                {
                    movie.Cinemas.Add(item);
                }

                // add to db
                context.Movies.Add(movie);

                // save to db
                context.SaveChanges();

                Console.WriteLine("Done adding Die Hard 2");
            }
        }

        private static void UpdateMovie()
        {
            using (dmaa0212a_5Entities context = new dmaa0212a_5Entities())
            {
                Console.WriteLine("Die Hard 2 changes price and location to only Aalborg");
                
                // get movie
                Movie movie = context.Movies.Single(m => m.Title == "Die Hard 2");

                // update info
                movie.Price = 60;
                // remove all existing cinemas
                var cinemas = movie.Cinemas.ToList();
                cinemas.ForEach(c => movie.Cinemas.Remove(c));
                // add cinema in aalborg
                movie.Cinemas.Add((from c in context.Cinemas where c.location == "Aalborg" select c).Single());

                // save to db
                context.SaveChanges();

                Console.WriteLine("Die Hard 2 updated!");
            }
        }

        private static void DeleteMovie()
        {
            using (dmaa0212a_5Entities context = new dmaa0212a_5Entities())
            {
                Console.WriteLine("Removing Die Hard 2 as movie");

                Movie movie =
                    (from m in context.Movies
                    where m.Title == "Die Hard 2"
                    select m).SingleOrDefault();

                if (movie != null)
                {
                    // remove from db
                    //context.Entry(movie).State = System.Data.EntityState.Deleted; DOES THE SAME AS BENEATH
                    context.Movies.Remove(movie);
                    // dependencies is handled by foreign keys cascade, much eaiser than doing it here!

                    /*
                     * You can delete an entity by two way:
                        If DBContext already loaded entity which you are going to delete then you can delete it using Set method:

                        dbCtx.Set(Teacher).Remove(newtchr); 

                        or

                        dbCtx.Teachers.Remove(newtchr);

                        If entity is not loaded in the DBContext then you can use Entry method to mark entity as deleted:

                        dbCtx.Entry(tchr).State = System.Data.EntityState.Deleted;
                        So this way you can easily delete an entity.
                     */
                    
                    // save to db
                    context.SaveChanges();
                }

                Console.WriteLine("Done removing");
            }
        }
    }
}
